#pragma once

#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/asio/io_service.hpp>

#include "torrent/fwd_decl.hpp"
#include "torrent/Client.hpp"

namespace torrent {

class Manager
{
private:

public:
	Manager(unsigned short port);
	~Manager();
	void openTorrent(const std::string& filePath);
	std::size_t run();
	void stop();
	unsigned short port();

	void startAccept();
	void handleAccept(const boost::system::error_code& error, P2PSessionPtr session);

	Client& getClient() { return _client; }
	boost::asio::io_service& ioService() { return _ioService; }
	int getMaxSessionPerManager() { return _maxSessionPerManager; }

	std::string workingPath() { return _client._workingPath; } //.empty()?"./":_client._workingPath; }
	std::string storagePath() { return _client._storagePath; } //.empty()?"./":_client._stroagePath; }

	P2PSessionPtr newP2PSession();
	void reportError(P2PSessionPtr session);

	void assignSessionToJob(P2PSessionPtr session, const std::string& infoHash);

private:
	void clear();
	void addPortMapping();
	void removePortMappling();

private:
	boost::asio::io_service _ioService;
	boost::asio::ip::tcp::endpoint _endpoint;
	boost::asio::ip::tcp::acceptor _acceptor;

	JobList _jobs;
	SessionList _p2pSessions;
	torrent::Client _client;
	unsigned int _maxSessionPerManager;
	bool _acceptInProgress;
};

} // namespace torrent
